﻿<%
'''核心入口类
Class Ashapo_Sa_Class
	'RegExp对象
	Private s_regex
	'解析后的视图代码
	Private s_vcode
	'''运行代码的前修饰符,一般为变量定义
	Private s_vcodepre
	'''include的文件及代码(头部)遵循规定：先开始后结束，后开始先结束
	Private s_inccodepre
	'''include的代码(底部)
	Private s_inccodefix
	'''页面跳转标题,提示信息,跳转等待时间(秒),跳转页面地址
	Private s_msgTitle, s_message, s_waitSecond, s_jumpUrl
	'''在include前的代码,主要是载入设置和公用函数
	Private s_codepre
	'''Ecore/Use/Extends的析构触发代码段,编译的一致顺序是先进后出
	Private s_codefix
	'''当前G/M/A/T/L
	Private s_nowG, s_nowM, s_nowA, s_nowT, s_nowL
	'''可运行缓存文件路径/data/_cache/_run/cn/home/index_index.asp
	Private s_vcp
	'''action类文件路径/app/Action/home/indexAction.class.asp
	Private s_vfp
	'''处理后的缓存action类文件路径/data/_cache/_action/home/indexAction.class.asp
	Private s_ccp
	'''模板路径,用于Tpl.Display过程/app/[Tpl]/default/home/index/index.html
	Private s_vtp
	'''进行的数据库查询次数
	Public DbQueryTimes
	'''核心使用的[Err]/[Fso]/[Http]/[Ini]/[Log]/[Tpl]/类(使用特征命名)
	Public [E], [Fso], [Http], [Ini], [Log], [Tpl]
	
	'''构造
	Private Sub Class_Initialize()
		Session.CodePage = 65001
		Response.Charset = "UTF-8"
		s_vcode = ""
		s_vcodepre = ""
		s_inccodepre = ""
		s_inccodefix = ""
		Set s_regex = New RegExp
		s_regex.Global = True
		s_regex.IgnoreCase = True
		s_regex.Multiline = False
		s_msgTitle = ""
		s_message = ""
		s_waitSecond = 3
		s_jumpUrl = ""
		s_codepre = ""
		s_codefix = ""
		DbQueryTimes = 0
		Set [E] = New Ashapo_Err_Class
		Set [Fso] = New Ashapo_Fso_Class
		Set [Http] = New Ashapo_Http_Class
		Set [Ini] = New Ashapo_Ini_Class
		Set [Log] = New Ashapo_Log_Class
		Set [Tpl] = New Ashapo_Tpl_Class
	End Sub
	
	'''析构Err/[Fso]/[Log]/Tpl类
	Private Sub Class_Terminate()
		'在这里进行Ecore/Use/Extends的析构函数
		If s_codefix <> "" Then
			ExecuteGlobal(s_codefix)
		End If
		'析构核心
		Set [Tpl] = Nothing
		Set [Log] = Nothing
		Set [Ini] = Nothing
		Set [Http] = Nothing
		Set [Fso] = Nothing
		Set [E] = Nothing
		Set s_regex = Nothing
	End Sub
	
	'语言自动化时转化
	Private Function nowLang_()
		nowLang_ = Lcase(G(C_LANG_PARAM & ":s:" & C_DEFAULT_LANG))
		If nowLang_ = "_auto" Then
			Dim t_hal : t_hal = Left(Lcase(Request.ServerVariables("HTTP_ACCEPT_LANGUAGE")),4)
			If Instr(t_hal, "zh-c") > 0 Then
				nowLang_ = "cn"
			ElseIf Instr(t_hal, "zh") > 0 Then
				nowLang_ = "tw"
			ElseIf Instr(t_hal, "en") > 0 Then
				nowLang_ = "en"
			ElseIf Instr(t_hal, "fr") > 0 Then
				nowLang_ = "fr"
			ElseIf Instr(t_hal, "de") > 0 Then
				nowLang_ = "de"
			ElseIf Instr(t_hal, "jp") > 0 Then
				nowLang_ = "jp"
			ElseIf Instr(t_hal, "ko") > 0 Then
				nowLang_ = "ko"
			ElseIf Instr(t_hal, "es") > 0 Then
				nowLang_ = "es"
			ElseIf Instr(t_hal, "sv") > 0 Then
				nowLang_ = "sv"
			Else
				nowLang_ = Lcase(Request.ServerVariables("HTTP_ACCEPT_LANGUAGE"))
			End If
		End If
		'修复可能出现的空值
		If nowLang_ = "" Then
			nowLang_ = "cn"
		End If
		'如果APP中不含该语言包时则默认指定为cn
		If Not [Fso].IsFolder(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_LANG_FOLDER & "/" & nowLang_ & "/") Then
			nowLang_ = "cn"
		End If
	End Function
	
	'''构建GMATL核心设置(也可用于GMATL值更新)
	'初步获取GMATL信息(init模式下需要进行值更新才能得到准确的值)
	Private Sub buildConf_()
		s_nowG = G(C_GROUP_PARAM & ":s:" & C_DEFAULT_GROUP)
		s_nowM = G(C_MODULE_PARAM & ":s:" & C_DEFAULT_MODULE)
		s_nowA = G(C_ACTION_PARAM & ":s:" & C_DEFAULT_ACTION)
		s_nowL = nowLang_()
		s_nowT = C_DEFAULT_TEMPLATE
		s_vcp = C_WEB_PATH & "/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_run/" & s_nowL & "/" & s_nowG & "/" & s_nowM & C_CACHE_FITER & s_nowA & ".asp"
		'更新s_vfp/s_ccp/s_vtp
		s_vfp = C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_ACTION_FOLDER & "/" & s_nowG & "/" & s_nowM & C_ACTION_SUFFIX & ".asp"
		s_ccp = C_WEB_PATH & "/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_action/" & s_nowG & "/" & s_nowM & C_ACTION_SUFFIX & ".asp"
		s_vtp = Replace(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_TEMPLATE_FOLDER & "/" & s_nowG & "/" & s_nowT & "/" & s_nowM & "/" & s_nowA & C_TPL_EXT_SUFFIX, "//", "/")
	End Sub
	
	'''构建HTML缓存位置
	Private Function htmlPath_()
		Dim t_p : t_p = C_WEB_PATH & "/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_html/" & s_nowL & "/" & s_nowG & "/" & s_nowM & "/" & s_nowA & "/"
		Dim t_k
		'所有GET参数(不含GMAL及标识位)
		For Each t_k In Request.QueryString
			If t_k<>C_GROUP_PARAM And t_k<>C_MODULE_PARAM And t_k<>C_ACTION_PARAM And t_k<>C_LANG_PARAM And t_k<>C_DISABLE_HTML_FITER Then
				t_p = t_p & t_k & "-" & Request.QueryString(t_k) & "_"
			End If
		Next
		t_p = Left(t_p, Len(t_p)-1)
		t_p = t_p & ".html"
		htmlPath_ = t_p
	End Function
	
	'''设置是否进行当前页面HTML静态缓存
	'(在页面渲染前设置都有效,可以进行逻辑判断生成)
	'设置该属性为True时即可以对当前页面进行缓存
	'对应缓存页面应是在多次运行时无逻辑变动(因为使用HTTP进行了二次访问,当然,既然进行了HTML缓存那肯定就是因为无逻辑变动)
	'内置一个特殊的GET值,用于判断是否要进行HTML静态化(防止死循环)
	'p_b:布尔值,是否生成HTML
	Public Property Let HTML(Byval p_b)
		'需要更新构建当前GMALT
		buildConf_()
		If p_b Then
			'标识位为空时则进行HTML缓存
			If Request.QueryString(C_DISABLE_HTML_FITER)="" Then
				'HTML缓存位置
				Dim t_hp : t_hp = htmlPath_()
				'HTML缓存清空交由Tool类和程序逻辑完成
				If Not [Fso].IsFile(t_hp) Then
					'访问当前已缓存的asp运行文件
					If [Fso].IsFile(s_vcp) Then
						[Http].Url = s_vcp & "?" & Request.QueryString & "&" & C_DISABLE_HTML_FITER & "=1"
						Dim t_h : t_h = [Http].Open()
						'保存到HTML文件夹
						Call [Fso].CreateFile(t_hp, t_h, True)
					End If
				End If
			End If
		End If
	End Property
	
	'''判断类代码中是否包含指定的公有函数
	'p_f:函数名称
	'p_s:代码段
	Private Function hasFunSub_(Byval p_f, Byval p_s)
		s_regex.Pattern = "[Public]?[\s]*[Sub|Function]{1}[\s]*[\[]?" & p_f & "[\]]?[\s]*\([^\)]*\)"
		If s_regex.Test(p_s) Then
			hasFunSub_ = True
		Else
			hasFunSub_ = False
		End If
	End Function
	
	'''设置页面跳转标题
	'p_t:标题字符串
	Public Property Let Title(Byval p_t)
		s_msgTitle = p_t
	End Property
	
	'''设置页面跳转提示信息
	'p_m:提示信息字符串
	Public Property Let Message(Byval p_m)
		s_message = p_m
	End Property
	
	'''设置页面跳转等待时间(秒)
	'p_s:等待的秒数(数字)
	Public Property Let WaitSecond(Byval p_s)
		s_waitSecond = p_s
	End Property
	
	'''设置页面跳转页面地址
	'p_u:跳转的链接
	Public Property Let JumpUrl(Byval p_u)
		s_jumpUrl = p_u
	End Property
	
	'''由文件路径获取完整的include代码(包括内部再include)
	'p_p:文件路径
	Private Function incReadByFile_(Byval p_p)
		Dim t_c, t_m, t_rule, t_inc, t_incFile, t_incStr
		t_c = [Fso].ReadFile(p_p)
		If IsN(t_c) Then
			Exit Function
		End If
		t_c = RegReplace(t_c, "<"&"%"&" *?@.*?%"&">", "")
		t_c = RegReplace(t_c, "(<"&"%"&"[^>]+?)(option +?explicit)([^>]*?%"&">)", "$1'$2$3")
		t_rule = "<!-- *?#include +?(file|virtual) *?= *?""??([^"":?*\f\n\r\t\v]+?)""?? *?-->"
		If RegTest(t_c, t_rule) Then
			Set t_inc = RegMatch(t_c,t_rule)
			For Each t_m In t_inc
				If LCase(t_m.SubMatches(0))="virtual" Then
					t_incFile = t_m.SubMatches(1)
				Else
					t_incFile = Mid(p_p,1,InstrRev(p_p, IIF(Instr(p_p,":")>0,"\","/"))) & t_m.SubMatches(1)
				End If
				t_incStr = incReadByFile_(t_incFile)
				t_c = Replace(t_c,t_m,t_incStr)
			Next
			Set t_inc = Nothing
		End If
		incReadByFile_ = t_c
	End Function
	
	'''由代码片段获取完整的include代码(包括内部再include)
	'p_p指定该代码片段应处在的文件夹路径
	'p_s:代码段
	'p_p:代码段应处在的文件夹路径
	Private Function incReadByCode_(Byval p_s, Byval p_p)
		Dim t_c, t_m, t_rule, t_inc, t_incFile, t_incStr
		t_c = p_s
		If IsN(t_c) Then
			Exit Function
		End If
		t_c = RegReplace(t_c, "<"&"%"&" *?@.*?%"&">", "")
		t_c = RegReplace(t_c, "(<"&"%"&"[^>]+?)(option +?explicit)([^>]*?%"&">)", "$1'$2$3")
		t_rule = "<!-- *?#include +?(file|virtual) *?= *?""??([^"":?*\f\n\r\t\v]+?)""?? *?-->"
		If RegTest(t_c,t_rule) Then
			Set t_inc = RegMatch(t_c,t_rule)
			For Each t_m In t_inc
				If LCase(t_m.SubMatches(0))="virtual" Then
					t_incFile = t_m.SubMatches(1)
				Else
					t_incFile = p_p & t_m.SubMatches(1)
				End If
				t_incStr = incReadByFile_(t_incFile)
				t_c = Replace(t_c,t_m,t_incStr)
			Next
			Set t_inc = Nothing
		End If
		incReadByCode_ = t_c
	End Function
	
	'''格式化include代码
	'p_s:要格式化的代码
	Private Function getIncCode_(Byval p_s)
		Dim t_ts, t_c, t_tc, t_sc, t_st, t_en
		'Unix到Dos
		'p_s = Replace(p_s, vbLf, vbCrLf)
		'格式化隔行/%/>/</%/这种情况,防止Select语句被非法阻断
		p_s = RegReplace(p_s, "%"&">[\n\s*\r]+<"&"%", vbCrLf)
		'Response.Write(p_s)
		'开始
		t_c = "" : t_st = 1 : t_en = Instr(p_s,"<"&"%") + 2
		t_sc = "Response.Write "
		While t_en > t_st + 1
			t_ts = Mid(p_s, t_st, t_en-t_st-2)
			t_st = Instr(t_en, p_s, "%"&">") + 2
			If Has(t_ts) Then
				t_ts = Replace(t_ts, """", """""")
				t_ts = Replace(t_ts, vbCrLf, """&vbCrLf&""")
				t_c = t_c & t_sc & """" & t_ts & """" & vbCrLf
			End If
			t_ts = Mid(p_s, t_en, t_st-t_en-2)
			t_tc = RegReplace(t_ts, "^\s*=\s*", t_sc) & vbCrLf
			t_c = t_c & t_tc
			t_en = Instr(t_st, p_s, "<"&"%") + 2
		Wend
		t_ts = Mid(p_s, t_st)
		If Has(t_ts) Then
			t_ts = Replace(t_ts, """", """""")
			t_ts = Replace(t_ts, vbcrlf, """&vbCrLf&""")
			t_c = t_c & t_sc & """" & t_ts & """" & vbCrLf
		End If
		'getIncCode_ = Core.RegReplace(t_c,"(\n\s*\r)+",vbCrLf)
		'消除空行
		getIncCode_ = RegReplace(t_c, "(\n\s*\r)+", "")
	End Function
	
	'''运行原生意大利面条代码
	'本函数是导致调试困难的原因,如果出现错误请注释掉On Error Resume Next进行分析
	'p_s:要运行的代码
	Private Sub run_(Byval p_s)
		'On Error Resume Next
		'Response.Write(p_s)
		'Response.End
		'Response.Write(getIncCode_(incReadByCode_(p_s, p_folderPath)))
		'Response.Flush
		ExecuteGlobal(getIncCode_(incReadByCode_(p_s, "")))
		If Err.Number<>0 Then
			'抛出错误,Log信息收集
			'直接输出查看错误
			Response.Write(getIncCode_(incReadByCode_(p_s, "")))
			Response.End
			'[E].Throw(22)
		End If
	End Sub
	
	'''动态include,(模拟php的require)不含编译(可以进行逻辑判断/建议少用,性能不行)
	'本函数是导致调试困难的原因,如果出现错误请注释掉On Error Resume Next进行分析
	'p_p:文件路径
	Public Sub Require(Byval p_p)
		'On Error Resume Next
		ExecuteGlobal(getIncCode_(incReadByFile_(p_p)))
		If Err.Number<>0 Then
			'抛出错误,Log信息收集
			Response.Write(getIncCode_(incReadByFile_(p_p)))
			Response.End()
			'[E].Throw(21)
		End If
	End Sub
	
	'''动态include,(模拟php的require)不含编译(可以进行逻辑判断/建议少用,性能不行)
	'仅载入一次
	'p_p:文件路径
	Public Sub RequireOnce(Byval p_p)
	End Sub
	
	'''动态include,含编译
	'p_p:文件路径
	Public Sub Include(Byval p_p)
		Require(p_p)
		'无出错后进行Include编译
		s_inccodepre = s_inccodepre & "<!--#include virtual=""" & p_p & """-->" & vbcrlf
	End Sub
	
	'''动态include，含编译，仅载入一次
	'p_p:文件路径
	Public Sub IncludeOnce(Byval p_p)
		If InStr(s_inccodepre, "<!--#include virtual=""" & p_p & """-->")=0 Then
			Include(p_p)
		End If
	End Sub

	'''修改代码,除去相关的Sa对象的一次性使用函数
	'对:不换行的处理
	'p_s:要格式化的代码
	Private Function weedSa_(Byval p_s)
		'删除Include调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.Include[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除IncludeOnce调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.IncludeOnce[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除Object调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.Object[\(]?[ |	]*""([^""]*)""\,[ |	]*""([^""]*)""\,[ |	]*\d[ |	]*[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除Use调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.Use[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除Ext调用,已废弃
		s_regex.Pattern = "(Call[ |	]*)?Sa.Ext[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除Ecore调用,已废弃
		s_regex.Pattern = "(Call[ |	]*)?Sa.Ecore[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除Extends调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.Extends[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除Dim调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.Dim[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除DimObject调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.DimObject[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除Display调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.Display[\(]?""([^""]*)""[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除Show调用
		s_regex.Pattern = "(Call[ |	]*)?Sa.Show[\(]?[\)]?[ |	]*[\:]?[ |	]*"
		p_s = s_regex.Replace(p_s,"")
		'删除注释
		s_regex.Pattern = "[\r\n]{1}[\s|	]*[']+[^\r\n]*"
		p_s = s_regex.Replace(p_s,"")
		'删除多余空行
		s_regex.Pattern = "\n[\s|	]*\r"
		p_s = s_regex.Replace(p_s,"")
		weedSa_ = p_s
	End Function
	
	'''通过ini语言文件返回语言包代码
	'p_f:语言包ini文件路径
	Private Function lang_(Byval p_f)
		Dim t_fc : t_fc = [Fso].ReadFile(p_f)
		Dim t_fl : t_fl = Split(t_fc, vbcrlf)
		Dim t_c : t_c = ""
		Dim t_a, t_x
		For Each t_x In t_fl
			'去掉节点
			If InStr(t_x, "[")<>1 Then
				'含双引号情况
				If InStr(t_x, Chr(34)) > 0 Then
					t_a = Split(t_x, "=")
					If UBound(t_a) = 1 Then
						If InStr(t_x, """&")>0 Or  InStr(t_x, "&""")>0 Then
							t_c = t_c & "Dim " & C_LANG_PREFIX & t_a(0) & " : " & C_LANG_PREFIX & t_a(0) & " = " & t_a(1) & vbcrlf
						Else
							t_c = t_c & "Const " & C_LANG_PREFIX & t_a(0) & " = " & t_a(1) & vbcrlf
						End If
					End If
				Else
					'普通情况
					t_a = Split(t_x, "=")
					If UBound(t_a) = 1 Then
						t_c = t_c & "Const " & C_LANG_PREFIX & t_a(0) & " = " & Chr(34) & t_a(1) & Chr(34) & vbcrlf
					End If
				End If
			End If
		Next
		t_c = "<" & Chr(37) & vbcrlf & t_c & Chr(37) & ">"
		lang_ = t_c
	End Function
	
	'''编译生成需要的语言文件
	'''该函数仅在生成时有效,且使用了ashapo核心fso
	'''20140612(大动静修改,简化语言包编译过程)
	'p_s:按运行模式指定语言包编译模式(附加run模式,只返回代码段,不进行文件生成,outer模式,返回入口文件代码)
	Private Sub byLang_(Byval p_s)
		If p_s = "" Then
			p_s = C_APP_STATUS
		End If
		p_s = Lcase(p_s)
		'系统是否需要编译单文件语言包(仅在Debug下不生成)
		Dim t_mf : t_mf = IIF(p_s="debug", False, True)
		'ashapo底层语言包
		Dim t_shal : t_shal = C_WEB_PATH & "/" & C_CORE_FOLDER & "/Lang/" & s_nowL & ".ini"
		Dim t_cshal : t_cshal = C_WEB_PATH & "/" & C_DATA_FOLDER &"/" & C_CACHE_FOLDER & "/_lang/" & s_nowL & "__shapo.asp"
		'如果底层语言包没有则使用cn底层语言包
		If Not [Fso].IsFile(t_shal) Then
			t_shal = C_WEB_PATH & "/" & C_CORE_FOLDER & "/Lang/cn.ini"
			t_cshal = C_WEB_PATH & "/" & C_DATA_FOLDER &"/" & C_CACHE_FOLDER & "/_lang/cn__shapo.asp"
		End If
		'加载到s_inccodepre的代码段
		Dim t_out : t_out = ""
		'代码段
		Dim t_shac : t_shac = lang_(t_shal)
		If t_mf Then
			If [Fso].CreateFile(t_cshal, t_shac, 0) Then
				t_out = t_out & "<!--#include virtual=""" & t_cshal & """-->" & vbcrlf
			Else
				'错误代码未更新
				[E].Throw(36)
			End If
		End If
		'APP分组语言包
		Dim t_appl : t_appl = C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_LANG_FOLDER & "/" & s_nowL & "/" & s_nowG & ".ini"
		Dim t_cappl : t_cappl = C_WEB_PATH & "/" & C_DATA_FOLDER &"/" & C_CACHE_FOLDER & "/_lang/" & s_nowL & "_" & s_nowG & ".asp"
		Dim t_appc : t_appc = ""
		If [Fso].IsFile(t_appl) Then
			t_appc = lang_(t_appl)
			If t_mf Then
				If [Fso].CreateFile(t_cappl, t_appc, 0) Then
					t_out = t_out & "<!--#include virtual=""" & t_cappl & """-->" & vbcrlf
				Else
					'错误代码未更新
					[E].Throw(36)
				End If
			End If
		End If
		'开始
		run_(t_shac & t_appc)
		Select Case p_s
		Case "debug"
			'DoNothing,仅运行代码
		Case "default","speed","record"
			'将语言包加载语句加入到s_inccodepre
			's_inccodepre = s_inccodepre & t_out
			's_inccodepre = t_out & s_inccodepre
			s_codepre = s_codepre & t_out
		Case "outer"
			'考虑废弃
			If IsIn(Lcase(C_AppStatus), Array("default", "record")) Then
				byLang_ = t_os1
			ElseIf IsIn(Lcase(C_AppStatus), Array("debug","speed")) Then
				byLang_ = t_os2
			Else
				'其他模式出错,置空
				byLang_ = ""
			End If
		End Select
	End Sub
	
	'''编译公用函数
	'由于公用函数可能使用sa对象，需要对其进行编译
	Private Sub byCommon_()
		Dim t_p : t_p = C_WEB_PATH & "/" & C_APP_FOLDER &"/" & C_COMMON_FOLDER & "/"
		Dim t_sp : t_sp = C_WEB_PATH & "/" & C_DATA_FOLDER &"/" & C_CACHE_FOLDER & "/_common/"
		Dim t_a : t_a = Split(C_EXT_COMMON, ",")
		Dim t_i, t_s
		For t_i = 0 To UBound(t_a)
			If [Fso].IsFile(t_p & t_a(t_i) & ".asp") Then
				Require(t_p & t_a(t_i) & ".asp")
				'无出错后进行Common编译
				t_s = weedSa_([Fso].ReadFile(t_p & t_a(t_i) & ".asp"))
				If C_APP_STATUS <> "debug" Then
					If [Fso].CreateFile(t_sp&t_a(t_i)&".asp", t_s,0) Then
						s_inccodepre = s_inccodepre & "<!--#include virtual=""" & t_sp&t_a(t_i)&".asp" & """-->" & vbcrlf
					Else
						[E].Throw(41)
					End If
				End If
			Else
				'公用函数文件不存在，抛出错误(非严重错误)
				[E].Throw(41111)
			End If
		Next
	End Sub
	
	'''变量预定义
	'''这是改进版的变量赋值Sign,放弃使用ExecuteGlobal，改用定义全局变量
	'''支持数组定义
	'''例参数"arr|5"表示定义名为arr的一维数组,其数组大小为6(最大可用下标5)
	'''例参数"arr|5|4"表示定义名为arr的二维数组,其数组大小为6X5
	'p_p:变量名
	Public Sub [Dim](Byval p_p)
		If InStr(p_p, "|")>0 Then
			Dim t_s, t_a, t_p
			t_a = Split(p_p, "|")
			t_s = t_a(0) & "(" & t_a(1)
			For i=2 To UBound(t_a)
				If IsNumeric(t_a(i)) Then
					t_s = t_s & "," & t_a(i)
				Else
					'本处错误代码未更新
					[E].Throw(3512)
				End If
			Next
			t_s = t_s & ")"
			t_p = t_s
			t_s = "Dim " & t_s
			If s_vcodepre = "" Then
				s_vcodepre =  t_s
			Else
				s_vcodepre = s_vcodepre & ", " & t_p
			End If
			ExecuteGlobal(t_s)
		Else
			If s_vcodepre = "" Then
				s_vcodepre =  "Dim " & p_p
			Else
				s_vcodepre = s_vcodepre & ", " & p_p
			End If
			ExecuteGlobal("Dim " & p_p)
		End If
	End Sub
	
	'''变量预定义
	'Assign和Dim的区别是Assign不会被格式化而每次都以ExecuteGlobal形式进行
	'Assign主要使用在跳转页面
	'使用效率上Dim>Assign,故能用Dim的地方请不要使用Assign
	'p_p:变量名
	Public Sub Assign(Byval p_p)
		If InStr(p_p, "|")>0 Then
			Dim t_str, t_arr
			t_arr = Split(p_p, "|")
			t_str = t_arr(0) & "(" & t_arr(1)
			For i=2 To UBound(t_arr)
				If IsNumeric(t_arr(i)) Then
					t_str = t_str & "," & t_arr(i)
				Else
					'本处错误代码未更新
					[E].Throw(3512)
				End If
			Next
			t_str = t_str & ")"
			t_str = "Dim " & t_str
			ExecuteGlobal(t_str)
		Else
			ExecuteGlobal("Dim " & p_p)
		End If
	End Sub
	
	'''对象预定义
	'对象有析构动作,如果采用变量预定义则析构工作无法执行
	'p_p:对象名
	Public Sub DimObject(Byval p_p)
		[Dim](p_p)
		s_inccodefix = "Set " & p_p & " = Nothing" & vbcrlf & s_inccodefix
	End Sub
	
	'''往s_codefix添加代码段
	'p_s:要添加的析构代码段
	Private Sub addCodeFix_(Byval p_s)
		If s_codefix = "" Then
			s_codefix = p_s
		Else
			s_codefix = p_s & " : " & s_codefix
		End If
	End Sub
	
	'''获取格式化后的代码,用于进行ExecuteGlobal运行
	'p_s:要格式化的代码
	Private Function formatCode_(Byval p_s)
		formatCode_ = getIncCode_(incReadByCode_(p_s, ""))
	End Function
	
	'''使用内置或APP扩展类
	'使用核心机制后,内置类与ashapo低耦合,可以任意添加其他类
	'p_f:类名(去掉Class)
	'p_n:实例化名(为空则为类名去掉Class)
	'p_t:指定类位置,0为自动(APP权重高),1为APP，2为内置Class
	Public Sub [Object](Byval p_f, Byval p_n, Byval p_t)
		Dim t_appcp : t_appcp = C_WEB_PATH & "/" & C_APP_FOLDER &"/" & C_CLASS_FOLDER & "/"
		Dim t_shacp : t_shacp = C_WEB_PATH & "/" & C_CORE_FOLDER &"/Class/"
		Dim t_fp
		If p_t<>1 And p_t<>2 Then
			'自动时判断位置
			If [Fso].IsFile(t_appcp & p_f & "_Class.asp") Then
				p_t = 1
			Else
				p_t = 2
			End If
		End If
		If p_n = "" Then
			p_n = p_f
		End If
		Select Case p_t
		Case 1
			t_fp = t_appcp & p_f & "_Class.asp"
		Case 2
			t_fp = t_shacp & p_f & "_Class.asp"
		End Select
		If [Fso].IsFile(t_fp) Then
			Require(t_fp)
			ExecuteGlobal("Dim " & p_n & " : Set " & p_n & " = New " & p_f & "Class")
		Else
			'出错处理
			[E].Throw(23)
		End If
		If Err.Number<>0 Then
			'抛出错误,Log信息收集
			[E].Throw(24)
		End If
		'添加析构
		'变更为Sa公有属性则在Ashapo类中进行析构
		addCodeFix_("Set " & p_n & " = Nothing")
		'无出错后进行Use编译
		s_inccodepre = s_inccodepre & "<!--#include virtual=""" & t_fp &"""-->" & vbcrlf
		s_inccodepre = s_inccodepre & "<" & "%" & "Dim " & p_n & " : Set " & p_n & " = New " & p_f & "Class" & "%" & ">" & vbcrlf
		'析构在Asp类中进行一次,生成缓存后手动析构
		s_inccodefix = "Set " & p_n & " = Nothing" & vbcrlf & s_inccodefix
	End Sub
	
	'''使用内置类(直接根类名实例化类)
	'''本处Set NoThing无需在程序中手动执行
	'p_f:类名(去掉Class)
	Public Sub Use(Byval p_f)
		Call [Object](p_f, p_f, 0)
	End Sub
	
	'''伪继承(应使用前缀标识,这样就可以避开关键字的冲突)
	'''多级继承的考虑
	'''本处Set NoThing应在生成的缓存文件中添加自动执行
	''伪继承文件名后缀和配置文件当前不关联,后期需要修改
	'p_f:Action类名(去掉Class)
	Public Sub Extends(Byval p_f)
		Dim t_a : t_a = Replace(p_f, "Action", "")
		Dim t_fp : t_fp = C_WEB_PATH & "/" & C_APP_FOLDER &"/" & C_ACTION_FOLDER & "/" & t_a & C_ACTION_SUFFIX & ".asp"
		If [Fso].IsFile(t_fp) Then
			Require(t_fp)
			ExecuteGlobal("Dim " & C_ACTION_PREFIX & t_a & " : Set " & C_ACTION_PREFIX & t_a & " = New " & p_f)
		Else
			'出错处理
			[E].Throw(25)
		End If
		If Err.Number<>0 Then
			'抛出错误,Log信息收集
			[E].Throw(26)
		End If
		'添加析构
		addCodeFix_("Set " & C_ACTION_PREFIX & t_a & " = Nothing")
		'无出错后进行Extends编译
		Dim t_sp : t_sp = C_WEB_PATH & "/" & C_DATA_FOLDER &"/" & C_CACHE_FOLDER & "/_extends/" & t_a & C_ACTION_SUFFIX & ".asp"
		Dim t_s : t_s = weedSa_([Fso].ReadFile(t_fp))
		'构建缓存
		If Lcase(C_APP_STATUS) <> "debug" Then
			If Not [Fso].CreateFile(t_sp, t_s,0) Then
				[E].Throw(41)
			End If
		End If
		s_inccodepre = s_inccodepre & "<!--#include virtual=""" & t_sp & """-->" & vbcrlf
		s_inccodepre = s_inccodepre & "<" & Chr(37) & "Dim " & C_ACTION_PREFIX & t_a & " : Set " & C_ACTION_PREFIX & t_a & " = New " & p_f & Chr(37) & ">" & vbcrlf
		s_inccodefix = "Set " & C_ACTION_PREFIX & t_a & " = Nothing" & vbcrlf & s_inccodefix
	End Sub
	
	'''编译Action类文件,生成缓存
	'''编译处理包括:
	'''1.Asp.Extends,处理方法:改成在缓存文件include并进行实例化(set nothing的处理)
	'''2.Asp.Use,处理方法:改成在缓存文件include并进行实例化(set nothing的处理)
	'''3.Asp.Include,目前仅支持上下文无关include,且路径必须为绝对路径
	'''4.Asp.Model,处理方法:目前未启用
	'p_p:Action类文件路径
	Private Sub byAction_(Byval p_p)
		If Lcase(C_APP_STATUS) = "debug" Then
			Exit Sub
		End If
		Dim t_s : t_s = weedSa_([Fso].ReadFile(p_p))
		Dim t_sp : t_sp = C_WEB_PATH & "/" & C_DATA_FOLDER &"/" & C_CACHE_FOLDER & "/_action/" & Split(p_p, "/")(3) & "/" & Split(p_p, "/")(4)
		If Not [Fso].CreateFile(t_sp, t_s, 0) Then
			[E].Throw(41)
		End If
	End Sub
	
	'''添加cache_asp_list
	'p_p:缓存路径
	Private Sub addAspCache_(Byval p_p)
		Dim t_a,t_d,t_c : t_c = C_ASP_CACHE_APPKEY
		Dim t_k : t_k = C_WEB_PATH & "/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/cache.lock"
		'Lock文件不见了,即缓存文件被清除了
		If Not [Fso].IsFile(t_k) Then
			RemoveApp(t_c)
		End If
		If IsArray(GetApp(t_c)) Then
			If TypeName(GetApp(t_c)(0))="Dictionary" Then
				Set t_d = GetApp(t_c)(0)
				If Not t_d.Exists(p_p) Then
					t_d(p_p) = 1'其实只是要键名,赋值什么无所谓的
					'RemoveApp(t_c)
					t_a = Array(t_d)
					Call SetApp(t_c, t_a)
				End If
			Else
				Set t_d = Server.CreateObject(C_DICT_NAME)
				t_d(p_p) = 1
				t_a = Array(t_d)
				Call SetApp(t_c, t_a)
				If Not [Fso].IsFile(t_k) Then
					If Not [Fso].CreateFile(t_k, "删除ASP缓存请将该文件一并删除!",1) Then
						'本处的错误输出要进行修改
						[E].Throw(111)
					End If
				End If
			End If
		Else
			Set t_d = Server.CreateObject(C_DICT_NAME)
			t_d(p_p) = 1
			t_a = Array(t_d)
			Call SetApp(t_c, t_a)
			If Not [Fso].IsFile(t_k) Then
				If Not [Fso].CreateFile(t_k, "删除ASP缓存请将该文件一并删除!",1) Then
					[E].Throw(111)
				End If
			End If
		End If
	End Sub
	
	'''添加cache_html_list
	'p_p:缓存路径
	Private Sub addHtmlCache_(Byval p_p)
		Dim t_a,t_d,t_c : t_c = C_HTML_CACHE_APPKEY
		'便于程序处理的判断键名
		Dim t_e : t_e = Request.ServerVariables("SCRIPT_NAME") & "?" & Request.QueryString
		Dim t_k : t_k = C_WEB_PATH & "/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_html/html.lock"
		'Lock文件不见了,即HTML缓存文件被清除了
		If Not [Fso].IsFile(t_k) Then
			RemoveApp(t_c)
		End If
		If IsArray(GetApp(t_c)) Then
			If TypeName(GetApp(t_c)(0))="Dictionary" Then
				Set t_d = GetApp(t_c)(0)
				If Not t_d.Exists(t_e) Then
					t_d(t_e) = p_p	'键名用于判断,键值用于存储HTML路径
					'RemoveApp(t_c)
					t_a = Array(t_d)
					Call SetApp(t_c, t_a)
				End If
			Else
				Set t_d = Server.CreateObject(C_DICT_NAME)
				t_d(t_e) = p_p
				t_a = Array(t_d)
				Call SetApp(t_c, t_a)
				If Not [Fso].IsFile(t_k) Then
					If Not [Fso].CreateFile(t_k, "删除HTML缓存请将该文件一并删除!",1) Then
						'本处的错误输出要进行修改
						[E].Throw(111)
					End If
				End If
			End If
		Else
			Set t_d = Server.CreateObject(C_DICT_NAME)
			t_d(p_p) = 1
			t_a = Array(t_d)
			Call SetApp(t_c, t_a)
			If Not [Fso].IsFile(t_k) Then
				If Not [Fso].CreateFile(t_k, "删除HTML缓存请将该文件一并删除!",1) Then
					'本处的错误输出要进行修改
					[E].Throw(111)
				End If
			End If
		End If
	End Sub
	
	'''确认视图路径
	'p_tp:对应的模板文件路径
	Private Sub makeSureView_(Byval p_tp)
		If Not p_tp= "" Then
			'变更Tpl路径(需要改进下)
			s_vtp = p_tp
			If Not Left(p_tp,1) = "/" Then
				Dim t_t, t_g, t_m, t_a
				t_a = s_nowA
				t_t = s_nowT
				t_g = s_nowG
				t_m = s_nowM
				Dim t_a1, t_a2, t_a3
				t_a1 = ParamRev(p_tp)
				t_a = t_a1(0)
				If Has(t_a1(1)) Then
					t_a2 = ParamRev(t_a1(1))
					t_m = t_a2(0)
					If Has(t_a2(1)) Then
						t_a3 = ParamRev(t_a2(1))
						t_t = t_a3(0)
						If Has(t_a3(1)) Then
							t_g = t_a3(1)
						End If
					End If
				End If
				s_vtp = Replace(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_TEMPLATE_FOLDER & "/" & t_g & "/" & t_t & "/" & t_m & "/" & t_a & C_TPL_EXT_SUFFIX, "//", "/")
			End If
		End If
	End Sub
	
	'''建立执行页面缓存
	Private Sub buildCache_()
		'''如果无缓存action类文件则进行编译建立
		byAction_(s_vfp)
		'''修改v代码
		Dim t_v, t_vp : t_vp = ""	'v代码的首部添加字符
		'''装入s_vcodepre(全局Dim变量)
		If Not Trim(s_vcodepre) = "" Then
			t_vp = "<" & Chr(37) & Trim(s_vcodepre) & Chr(37) & ">" & vbcrlf
		End If
		'''include所需代码
		'include底层设置
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Conf/object.asp""-->" & vbcrlf
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Conf/config.asp""-->" & vbcrlf
		'include底层函数
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Common/runtime.asp""-->" & vbcrlf
		'include 设置/公用函数
		t_vp = t_vp & s_codepre
		'include底层类
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Core/Err.asp""-->" & vbcrlf
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Core/Fso.asp""-->" & vbcrlf
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Core/Http.asp""-->" & vbcrlf
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Core/Ini.asp""-->" & vbcrlf
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Core/Log.asp""-->" & vbcrlf
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Core/Tpl.asp""-->" & vbcrlf
		t_vp = t_vp & "<!--#include virtual=""" & C_WEB_PATH & "/" & C_CORE_FOLDER & "/Core/Sa.asp""-->" & vbcrlf
		t_vp = t_vp & "<" & Chr(37) & "Dim Sa : Set Sa = New Ashapo_Sa_Class" & Chr(37) & ">" & vbcrlf
		'include use/Include/Extends
		t_vp = t_vp & s_inccodepre
		'include Action类
		t_vp = t_vp & "<!--#include virtual=""" & s_ccp & """-->" & vbcrlf
		'实例化Action
		t_vp = t_vp & "<" & Chr(37) & "Dim " & C_ACTION_PREFIX & s_nowM & " : Set " & C_ACTION_PREFIX & s_nowM & " = New " & s_nowM & "Action : " & C_ACTION_PREFIX & s_nowM & "." & s_nowA & "()" & Chr(37) & ">"
		'''修改v代码,include缓存c代码
		t_v = t_vp & s_vcode
		'''析构类
		t_v = t_v & "<" & Chr(37) & vbcrlf
		'use/Include/Extends先执行
		t_v = t_v & s_inccodefix
		'主体Action
		t_v = t_v & "Set " & C_ACTION_PREFIX & s_nowM & " = Nothing" & vbcrlf
		t_v = t_v & "Set Sa = Nothing" & vbcrlf
		t_v = t_v & Chr(37) & ">"
		't_v = Replace(t_v, "%" & "><" & "%" , "")
		'''删除多余空行
		s_regex.Pattern = "\n[\s|	]*\r"
		t_v = s_regex.Replace(t_v,"")
		'''保存修改后代码
		Select Case Lcase(C_APP_STATUS)
		Case "default","record"
			If [Fso].CreateFile(s_vcp, t_v, 0) Then
				addAspCache_(s_vcp)
			Else
				[E].Throw(42)
			End If
		Case "speed"
			t_v = incReadByCode_(t_v,"")
			t_v = weedSa_(t_v)
			If [Fso].CreateFile(s_vcp, t_v, 1) Then
				addAspCache_(s_vcp)
			Else
				[E].Throw(42)
			End If
		Case "debug"
			'Do Nothing
		End Select
	End Sub
	
	'''渲染指定视图
	'与Display\Show过程不同的是Render可以进行逻辑判断,但是在性能上不如二者
	'p_tp:对应的模板文件路径
	Public Sub Render(Byval p_tp)
		buildConf_()
		makeSureView_(p_tp)
		Dim t_v, t_p
		'编译的视图缓存
		t_p = C_WEB_PATH & "/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_tpl/" & Replace(s_vtp, C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_TEMPLATE_FOLDER & "/", "")
		If [Fso].IsFile(t_p) Then
			t_v = [Fso].ReadFile(t_p)
		'实时解析
		ElseIf [Fso].IsFile(s_vtp) Then
			t_v = [Fso].ReadFile(s_vtp)
			t_v = [Tpl].Resolve(t_v)
			Call [Fso].CreateFile(t_p, t_v, False)
		Else
			SE(110)
		End If
		run_(t_v)
	End Sub
	
	'''生成缓存文件并运行结果
	'''该函数仅在生成时有效,且使用了ashapo核心fso
	'Display应针对不同运行模式生成不同的缓存文件
	'p_tp:对应的模板文件路径
	Public Sub Display(Byval p_tp)
		Dim t_v, t_r
		makeSureView_(p_tp)
		If [Fso].IsFile(s_vcp) Then
			'''直接运行代码
			addAspCache_(s_vcp)
			Server.Transfer(s_vcp)
			Exit Sub
		Else
			'''获取v代码,本次运行意大利面条代码
			If [Fso].IsFile(s_vtp) Then
				t_v = [Fso].ReadFile(s_vtp)
				'''修改v代码,进行解析
				t_v = [Tpl].Resolve(t_v)
				s_vcode = t_v
			Else
				SE(110)
			End If
			run_(t_v)
		End If
	End Sub
	
	'''输出默认模板
	Public Sub Show()
		Display("")
	End Sub
	
	'''构建Success/Error的视图路径
	Private Function resultPath_(Byval p_n)
		buildConf_()
		Dim t_t, t_g, t_m, t_a
		t_a = s_nowA
		t_m = s_nowM
		t_g = s_nowG
		t_t = s_nowT
		Dim t_a1, t_a2, t_a3
		t_a1 = ParamRev(p_n)
		t_a = t_a1(0)
		If Has(t_a1(1)) Then
			t_a2 = ParamRev(t_a1(1))
			t_m = t_a2(0)
			If Has(t_a2(1)) Then
				t_a3 = ParamRev(t_a2(1))
				t_t = t_a3(0)
				If Has(t_a3(1)) Then
					t_g = t_a3(1)
				End If
			End If
		End If
		resultPath_ = C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_TEMPLATE_FOLDER & "/" & t_g & "/" & t_t & "/" & t_m & "/" & t_a & C_TPL_EXT_SUFFIX
	End Function
	
	'''获取Success/Error页面意大利面条代码
	'模版读取顺序:
	'1.所在分组内的模板Public:Success
	'2.Public分组下的Success
	'3.主题下的Success文件
	'4.Ashapo核心Success.[Tpl]
	'p_n:标识符(success/error)
	Private Function resultCode_(Byval p_n)
		buildConf_()
		Dim t_g : t_g = s_nowG
		Dim t_app : t_app = "%Ashapo_" & Ucase(Left(t_g,1)) & Lcase(Right(t_g, Len(t_g)-1)) & "_" & p_n & "_Code%"
		If Has(GetApp(t_app)) Then
			resultCode_ = GetApp(t_app)
		Else
			Dim t_fp
			Select Case Lcase(p_n)
			Case "success"
				'获取模版
				If C_TMPL_ACTION_SUCCESS = "" Then
					t_fp = C_WEB_PATH & "/" & C_CORE_FOLDER & "/Tpl/success.tpl"
				Else
					t_fp = resultPath_(C_TMPL_ACTION_SUCCESS)
				End If
			Case "error"
				'获取模版
				If C_TMPL_ACTION_ERROR = "" Then
					t_fp = C_WEB_PATH & "/" & C_CORE_FOLDER & "/Tpl/error.tpl"
				Else
					t_fp = resultPath_(C_TMPL_ACTION_ERROR)
				End If
			Case Else
				[E].Throw(110)
			End Select
			If [Fso].IsFile(t_fp) Then
				resultCode_ = formatCode_([Tpl].Resolve([Fso].ReadFile(t_fp)))
				Call SetApp(t_app, resultCode_)
			Else
				Response.Write(t_fp)
				Response.End
				'竟然找不到文件。
				[E].Throw(11110)
			End If
		End If
	End Function

	'''运行跳转页面代码
	'p_t:标识符(success/error)
	'p_m:显示的提示信息
	'本函数是导致调试困难的原因,如果出现错误请注释掉On Error Resume Next进行分析
	Private Sub resultRun_(Byval p_t, Byval p_m)
		On Error Resume Next
		Dim t_u : t_u = s_jumpUrl
		Dim t_m : t_m = p_m
		Select Case Lcase(p_t)
		Case "success"
			If s_jumpUrl = "" Then
				t_u = Request.ServerVariables("HTTP_REFERER")
			End If
		Case "error"
			If s_jumpUrl = "" Then
				t_u = ""
			End If
		Case Else
			If s_jumpUrl = "" Then
				t_u = ""
			End If
		End Select
		If t_m = "" Then
			t_m = s_message
		End If
		If p_m <> "" Then
			s_message = p_m
		End If
		Assign("T_Title") : T_Title = s_msgTitle
		Assign("T_Message") : T_Message = t_m
		Assign("T_JumpUrl") : T_JumpUrl = t_u
		Assign("T_WaitSecond") : T_WaitSecond = s_waitSecond
		'Response.Write(resultCode_(p_t))
		'Response.End
		ExecuteGlobal(resultCode_(p_t))
		If Err.Number<>0 Then
			'抛出错误,Log信息收集
			'Response.Write(resultCode_(p_t))
			'Response.End
			'Response.Flush
			[E].Throw(22)
		End If
	End Sub
	
	'''Success页面跳转
	'p_m:显示的提示信息
	Public Sub Success(Byval p_m)
		Call resultRun_("Success", p_m)
	End Sub
	
	'''Error页面跳转
	'p_m:显示的提示信息
	Public Sub [Error](Byval p_m)
		Call resultRun_("Error", p_m)
	End Sub
	
	'''Error页面跳转
	'Response.End
	'p_m:显示的提示信息
	Public Sub ErrorE(Byval p_m)
		Call resultRun_("Error", p_m)
		Response.End
	End Sub
	
	'''底层404、500的运行代码，不含环境变量，仅解析V代码
	'p_n:标识符(404/500)
	Private Function sysRunCode_(Byval p_n)
		buildConf_()
		Dim t_p, t_v : t_v = ""
		'优先使用分组下当前主题的文件
		t_p = Replace(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_TEMPLATE_FOLDER & "/" & s_nowG & "/" & s_nowT & "/" & p_n & C_TPL_EXT_SUFFIX, "//", "/")
		If Not [Fso].IsFile(t_p) Then
			'当前分组的文件
			t_p = Replace(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_TEMPLATE_FOLDER & "/" & s_nowG & "/" & p_n & C_TPL_EXT_SUFFIX, "//", "/")
			If Not [Fso].IsFile(t_p) Then
				'项目的文件
				t_p = Replace(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_TEMPLATE_FOLDER & "/" & p_n & C_TPL_EXT_SUFFIX, "//", "/")
				If Not [Fso].IsFile(t_p) Then
					'内置的404/500模板
					t_p = C_WEB_PATH & "/" & C_CORE_FOLDER & "/Tpl/" & p_n & ".tpl"
				End If
			End If
		End If
		If [Fso].IsFile(t_p) Then
			t_v = [Fso].ReadFile(t_p)
			t_v = [Tpl].Resolve(t_v)
			sysRunCode_ = t_v
		Else
			'竟然找不到文件。
			[E].Throw(11110)
		End If
	End Function
	
	'''系统底层模板是否存在，目前只有404或500(如果已存在返回true，否则进行建立，成功建立则返回true，否则返回false)
	'404为单独页面，505为include页面末端实现。
	'20140707暂停404/500实现
	'p_n:标识符(404/500)
	Private Function hasSysTpl_(Byval p_n)
		hasSysTpl_ = False
		Exit Function
		If Lcase(C_APP_STATUS)="debug" Then
			hasSysTpl_ = False
			Exit Function
		End If
		Dim t_cp : t_cp = "/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_system/page_" & p_n & ".asp"
		If [Fso].IsFile(t_cp) Then
			hasSysTpl_ = True
			Exit Function
		End If
		'当语言包无法生成成功时直接返回false
		'default/record模式下,语言包如果未生成直接返回false
		Dim t_alp : t_alp = "/" & C_APP_FOLDER & "/" & C_LANG_FOLDER & "/"
		Dim t_clp : t_clp = "/" & C_CORE_FOLDER & "/Lang/"
		Dim t_lcp : t_lcp = "/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_lang/"
		If IsIn(Lcase(C_APP_STATUS), Array("default", "record")) Then
			'底层lang
			Dim t_i,t_lf : t_lf = [Fso].Dir(t_clp, 1)
			For t_i = 0 To UBound(t_lf,2)
				If Not [Fso].CreateFile(t_lcp & "ashapo_" & [Fso].NameOfFile(t_lf(0,t_i)) & ".asp", lang_(t_clp & t_lf(0,t_i)), 0) Then
					hasSysTpl_ = False
					Exit Function
				End If
			Next
			'app各语言文件夹下common.ini
			t_lf = [Fso].Dir(t_alp, 2)
			For t_i = 0 To UBound(t_lf,2)
				If [Fso].IsFile(t_alp & t_lf(0,t_i) & "/common.ini") Then
					If Not [Fso].CreateFile(t_lcp & t_lf(0,t_i) & "_common.asp", lang_(t_alp & t_lf(0,t_i) & "/common.ini"), 0) Then
						hasSysTpl_ = False
						Exit Function
					End If
				End If
			Next
			'入口文件
			If Not [Fso].IsFile(t_lcp & "ashapo.asp") Then
				If Not [Fso].CreateFile(t_lcp & "ashapo.asp", byLang_("outer"), 0) Then
					hasSysTpl_ = False
					Exit Function
				End If
			End If
		End If
		'Response.End
		Dim  t_v : t_v = sysRunCode_(p_n)
		Select Case Cstr(p_n)
		Case "404"
			'404要加载语言包和类、函数等
			'语言包文件生成时发生错误时，理论顺序是语言包生成失败开始走500错误，500错误文件生成不了则显示底层500错误
			'当404错误发生时，进入底层文件编译流程，其他文件编译失败进入500错误，500错误文件生成不了则显示底层500错误
			'语言包文件生成应该发生在404和500之前
			'''修改v代码
			Dim t_vp : t_vp = ""	'v代码的首部添加字符
			'''include所需代码
			'include底层设置
			t_vp = t_vp & "<!--#include virtual=""/" & C_CORE_FOLDER & "/Conf/config.asp""-->" & vbcrlf
			'include用户设置
			't_vp = t_vp & "<!--#include virtual=""/" & C_APP_FOLDER & "/" & C_ConfFolder & "/config.asp""-->" & vbcrlf
			Dim t_cfg : t_cfg = Array("config", "conn", "rule", i_g)
			For t_i = 0 To UBound(t_cfg)
				If [Fso].IsFile("/" & C_APP_FOLDER & "/" & C_CONF_FOLDER & "/" & t_cfg(t_i) & ".asp") Then
					t_vp = t_vp & "<!--#include virtual=""/" & C_APP_FOLDER & "/" & C_CONF_FOLDER & "/" & t_cfg(t_i) & ".asp""-->" & vbcrlf
				End If
			Next
			'include底层函数
			Dim t_cf : t_cf = [Fso].Dir("/" & C_CORE_FOLDER & "/Common/", 1)
			For i = 0 To UBound(t_cf,2)
				t_vp = t_vp & "<!--#include virtual=" & Chr(34) & "/" & C_CORE_FOLDER & "/Common/" & t_cf(0,i) & Chr(34) & "-->" & vbcrlf
			Next
			t_vp = t_vp & byLang_("run") & vbcrlf
			'include会话全局变量(废弃)
			't_vp = t_vp & "<!--#include virtual=""/" & C_CORE_FOLDER & "/Conf/session.asp""-->" & vbcrlf
			'include Sa
			t_vp = t_vp & "<!--#include virtual=""/" & C_CORE_FOLDER & "/Core/Err.asp""-->" & vbcrlf
			t_vp = t_vp & "<!--#include virtual=""/" & C_CORE_FOLDER & "/Core/sa.asp""-->" & vbcrlf
			t_vp = t_vp & "<" & Chr(37) & "Dim Sa : Set Sa = New Ashapo_Sa_Class" & Chr(37) & ">" & vbcrlf
			'include用户函数
			Dim t_pflist : t_pflist = [Fso].Dir("/" & C_APP_FOLDER & "/" & C_COMMON_FOLDER & "/", 1)
			For i = 0 To UBound(t_pflist,2)
				t_vp = t_vp & "<!--#include virtual=""/" & C_APP_FOLDER & "/" & C_COMMON_FOLDER & "/" & t_pflist(0,i) & """-->" & vbcrlf
			Next
			t_vp = t_vp & "<" & Chr(37) & vbcrlf
			'状态
			t_vp = t_vp & "Response.Clear" & vbcrlf
			t_vp = t_vp & "Response.Status = ""404 Not Found""" & vbcrlf
			t_vp = t_vp & Chr(37) & ">"
			'''修改v代码,include缓存c代码
			t_v = t_vp & t_v
			'''析构类
			t_v = t_v & "<" & Chr(37) & vbcrlf
			t_v = t_v & "Set Sa = Nothing" & vbcrlf
			t_v = t_v & Chr(37) & ">"
			't_v = Replace(t_v, "%" & "><" & "%" , "")
			'''删除多余空行
			's_regex.Pattern = "(\n\r)|(^\r)|(\n$)"
			s_regex.Pattern = "\n\s*\r"
			t_v = s_regex.Replace(t_v,"")
			Select Case Lcase(C_APP_STATUS)
			Case "default","record"
				hasSysTpl_ = [Fso].CreateFile(t_cp, t_v, 0)
			Case "speed"
				hasSysTpl_ = [Fso].CreateFile(t_cp, t_v, 1)
			End Select
		Case "500"
			'500采用include所以不用加载任何东西，但是该500页面无法单独运行
			'Do Nothing
			Select Case Lcase(C_APP_STATUS)
			Case "default","record"
				hasSysTpl_ = [Fso].CreateFile(t_cp, t_v, 0)
			Case "speed"
				hasSysTpl_ = [Fso].CreateFile(t_cp, t_v, 1)
			End Select
		Case ""
			'应该还是要生成一个可以直接运行的500页面
			'这个页面可以单独运行来作为系统的500页面，保持体验一致
		Case Else
			'目前不支持其他类型
			hasSysTpl_ = False
			Exit Function
		End Select
	End Function
	
	'''404页面输出
	Public Sub Go404()
		If hasSysTpl_("404") Then
			Server.Transfer("/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_system/page_404.asp")
		Else
			If C_SEND_STATUS Then
				'发送404状态
				Response.Clear
				Response.Status = "404 Not Found"
			End If
			'byLang_("debug")
			run_(sysRunCode_("404"))
			Response.End
		End If
	End Sub
	
	'''500页面输出
	'步骤:由Errc获取最后的错误代码ID,include500代码运行获得代码错误提示
	'p_eid,p_title,p_msg为空时显示已定义内容
	Public Sub Go500(Byval p_eid, Byval p_title, Byval p_msg)
		If Has(p_eid) Then
			[E].Raise(p_eid)
		End If
		If Has(p_title) Then
			s_title = p_title
		End If
		If Has(p_msg) Then
			s_msg = p_msg
		End If
		If C_SEND_STATUS Then
			'发送500状态
			Response.Clear
			Response.Status = "500 Internal Server Error"
		End If
		If hasSysTpl_("500") Then
			Require("/" & C_DATA_FOLDER & "/" & C_CACHE_FOLDER & "/_system/page_500.asp")
		Else
			run_(sysRunCode_("500"))
		End If
		Response.End
	End Sub

	'''载入Sa运行前需要的文件
	'p_p:文件路径
	Private Sub incPreFile_(Byval p_p)
		Require(p_p)
		'无出错后进行Include编译
		s_codepre = s_codepre & "<!--#include virtual=""" & p_p & """-->" & vbcrlf
	End Sub
	
	'''载入APP设置(多次载入相同设置值会产生Const多次定义系统错误)
	'''注意本函数并未更新GMATL值,要手动更新
	Private Sub incAppConf_()
		'加载APP公用config
		Dim t_i, t_cfl, t_cfg, t_gcl, t_gcf
		t_cfg = C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_CONF_FOLDER & "/config.asp"
		If [Fso].IsFile(t_cfg) Then
			'使用Include直接对asp缓存进行设置加载
			incPreFile_(t_cfg)
			'加载扩展设置
			If C_EXT_CONFIG<>"" Then
				t_cfl = Split(C_EXT_CONFIG, ",")
				For t_i = 0 To UBound(t_cfl)
					If [Fso].IsFile(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_CONF_FOLDER & "/" & t_cfl(t_i) & ".asp") Then
						incPreFile_(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_CONF_FOLDER & "/" & t_cfl(t_i) & ".asp")
					End If
				Next
				'置空C_EXT_CONFIG,防止判断错误
				C_EXT_CONFIG = ""
			End If
		End If
		'更新s_nowG
		s_nowG = G(C_GROUP_PARAM & ":s:" & C_DEFAULT_GROUP)
		'加载分组config
		t_gcf = C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_CONF_FOLDER & "/" & s_nowG & "/config.asp"
		If [Fso].IsFile(t_gcf) Then
			'使用Include直接对asp缓存进行设置加载
			incPreFile_(t_gcf)
			'加载扩展设置
			If C_EXT_CONFIG<>"" Then
				t_gcl = Split(C_EXT_CONFIG, ",")
				For t_i = 0 To UBound(t_gcl)
					If [Fso].IsFile(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_CONF_FOLDER & "/" & s_nowG & "/" & t_gcl(t_i) & ".asp") Then
						incPreFile_(C_WEB_PATH & "/" & C_APP_FOLDER & "/" & C_CONF_FOLDER & "/" & s_nowG & "/" & t_gcl(t_i) & ".asp")
					End If
				Next
				'置空C_EXT_CONFIG,防止判断错误
				C_EXT_CONFIG = ""
			End If
		End If
	End Sub
	
	'加载底层的其他公用函数
	Private Sub incCoreFun_()
		Dim t_a : t_a = Array("common","alias")
		Dim t_i, t_p : t_p = C_WEB_PATH & "/" & C_CORE_FOLDER & "/Common/"
		For t_i = 0 To UBound(t_a)
			If [Fso].IsFile(t_p & t_a(t_i) & ".asp") Then
				incPreFile_(t_p & t_a(t_i) & ".asp")
			End If
		Next
	End Sub
	
	'''ashapo编译入口
	Public Sub Init()
		'首先加载设置,然后更新核心设置
		incAppConf_()
		buildConf_()
		'静态HTML页面先判断(自行构建HTML缓存路径,生成独立入口后再由%Ashapo_Html_Page%进行判断进而提升性能)
		Dim t_hp : t_hp = htmlPath_()
		If [Fso].IsFile(t_hp) Then
			'可运行缓存HTML文件,直接执行该文件
			addHtmlCache_(t_hp)
			Server.Transfer(t_hp)
		ElseIf [Fso].IsFile(s_vcp) Then
			'可运行缓存文件,直接执行该文件
			addAspCache_(s_vcp)
			Server.Transfer(s_vcp)
		Else
			'开始编译并加载语言包
			byLang_("")
			'加载核心公用函数
			incCoreFun_()
			'编译加载公用函数
			byCommon_()			
			'可运行缓存文件,运行该Action类(对应函数)一次,如带Display过程,则asp缓存文件已自动生成
			If [Fso].IsFile(s_vfp) Then
				'''进行函数判断,如果无该函数,则出现404错误
				Dim t_cc : t_cc = [Fso].ReadFile(s_vfp)
				If hasFunSub_(s_nowA, t_cc) Then
					Require(s_vfp)
				Else
					'如果只有视图也是可以显示的(改进)
					'运行到这步时性能已经完全下降
					'WE(404)
					Go404()
				End If
			Else
				'运行到这步时性能已经完全下降
				'WE(404)
				Go404()
			End If
			'Response.Clear
			ExecuteGlobal("Dim "& C_ACTION_PREFIX & s_nowM & " : Set "& C_ACTION_PREFIX & s_nowM & " = New " & s_nowM & "Action")
			ExecuteGlobal(C_ACTION_PREFIX & s_nowM & "." & s_nowA & "()")
			buildCache_()
		End If
	End Sub
End Class
%>